﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tradex.Market {

    /// <summary>
    /// This static class contains various helper methods for dealing with encoded market updates.
    /// </summary>
    public static class PriceHelper {

        /// <summary>
        /// This method returns the "real" market update size behind a price given a specific encoding.
        /// </summary>
        /// <param name="codedSize"></param>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502")]
        public static float GetActivitySize(PriceCoding codedSize) {
            switch (codedSize) {
                case PriceCoding.Undefined:
                    return float.NaN;
                case PriceCoding.B10EM9:
                    return 0.00000001f;
                case PriceCoding.B10EM8:
                    return 0.00000001f;
                case PriceCoding.B10EM7:
                    return 0.0000001f;
                case PriceCoding.B10EM6:
                    return 0.000001f;
                case PriceCoding.B10EM5:
                    return 0.00001f;
                case PriceCoding.B10EM4:
                    return 0.0001f;
                case PriceCoding.B10EM3:
                    return 0.001f;
                case PriceCoding.B10EM2:
                    return 0.01f;
                case PriceCoding.B10EM1:
                    return 0.1f;
                case PriceCoding.B10E0:
                    return 1f;
                case PriceCoding.B10EP1:
                    return 10f;
                case PriceCoding.B10EP2:
                    return 100f;
                case PriceCoding.B10EP3:
                    return 1000f;
                case PriceCoding.B10EP4:
                    return 10000f;
                case PriceCoding.B10EP5:
                    return 100000f;
                case PriceCoding.B10EP6:
                    return 1000000f;
                case PriceCoding.B10EP7:
                    return 10000000f;
                case PriceCoding.B10EP8:
                    return 100000000f;
                case PriceCoding.B10EP9:
                    return 1000000000f;

                case PriceCoding.B2EM9:
                    return 0.001953125f;
                case PriceCoding.B2EM8:
                    return 0.00390625f;
                case PriceCoding.B2EM7:
                    return 0.0078125f;
                case PriceCoding.B2EM6:
                    return 0.015625f;
                case PriceCoding.B2EM5:
                    return 0.03125f;
                case PriceCoding.B2EM4:
                    return 0.0625f;
                case PriceCoding.B2EM3:
                    return 0.125f;
                case PriceCoding.B2EM2:
                    return 0.25f;
                case PriceCoding.B2EM1:
                    return 0.50f;
                case PriceCoding.B2E0:
                    return 1f;
                case PriceCoding.B2EP1:
                    return 2f;
                case PriceCoding.B2EP2:
                    return 4f;
                case PriceCoding.B2EP3:
                    return 8f;
                case PriceCoding.B2EP4:
                    return 16f;
                case PriceCoding.B2EP5:
                    return 32f;
                case PriceCoding.B2EP6:
                    return 64f;
                case PriceCoding.B2EP7:
                    return 128f;
                case PriceCoding.B2EP8:
                    return 256f;
                case PriceCoding.B2EP9:
                    return 256f;

                default:
                    throw new ArgumentException("Inavlid ActivitySize defined", "codedSize");
            }

        }

        /// <summary>
        /// Decodes an encoded Activity value to a float.
        /// </summary>
        /// <param name="tick"></param>
        /// <param name="activitysSize"></param>
        /// <returns></returns>
        public static float PriceToSingle (UInt32 tick, PriceCoding activitysSize) {
            return tick * GetActivitySize(activitysSize);
        }

        /// <summary>
        /// Decodes an encoded market update to a float.
        /// </summary>
        /// <param name="tick"></param>
        /// <param name="activitysSize"></param>
        /// <returns></returns>
        public static float PriceToSingle(float tick, PriceCoding activitysSize) {
            return tick * GetActivitySize(activitysSize);
        }

        /// <summary>
        /// Decodes an encoded market update to a double.
        /// </summary>
        /// <param name="tick"></param>
        /// <param name="activitysSize"></param>
        /// <returns></returns>
        public static double PriceToDouble(UInt32 tick, PriceCoding activitysSize) {
            return tick * GetActivitySize(activitysSize);
        }

        /// <summary>
        /// Decodes an encoded market update to a double.
        /// </summary>
        /// <param name="activity"></param>
        /// <param name="activitysSize"></param>
        /// <returns></returns>
        public static double PriceToDouble(float activity, PriceCoding activitysSize) {
            return activity * GetActivitySize(activitysSize);
        }

    }
}
